package com.lz.concurrent.thread;

import java.util.concurrent.locks.LockSupport;

/**
 * ParkDemo..
 *
 * @see <a href="https://blog.csdn.net/u013332124/article/details/84647915">Thread.sleep、Object.wait、LockSupport.park 区别</a>
 *
 * @author Lizhong
 * @date 2020/4/7
 */
public class ParkDemo {
    private static Thread thread;

    /**
     * 3个测试分开进行，得出三条结论
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        Thread parkThread = new Thread(ParkDemo::park);
        Thread unparkThread = new Thread(ParkDemo::unpark);
        thread = parkThread;

        // 1. 顺序测试，只有unpark给了许可，不论顺序 park就不会阻塞
        // unparkThread.start();
        parkThread.start();

        // 2.中断测试
        // park方法不会抛出InterruptedException，但是它也会响应中断。park阻塞的线程也会立刻返回。
        // parkThread.interrupt();

        // 3. 获取锁测试
        Thread parkMonitor = new Thread(ParkDemo::parkMonitor);
        parkMonitor.start();

        parkThread.join();
        unparkThread.join();
        System.out.println("main over");
    }

    public static void park() {
        System.out.println("park begin");

        //等待获取许可，此时线程不会释放锁
        synchronized (ParkDemo.class) {
            LockSupport.park();
        }
        //输出thread over.true
        System.out.println("thread over." + Thread.currentThread().isInterrupted());

    }

    public static void unpark() {
        System.out.println("unpark begin");
        // 颁发许可
        LockSupport.unpark(thread);
        System.out.println("unpark thread over");

    }

    public static void parkMonitor() {
        System.out.println("开始获取锁");

        //等待获取许可，此时线程不会释放锁
        synchronized (ParkDemo.class) {
            System.out.println("获取锁成功");
        }

        System.out.println("取锁过程完毕");

    }
}
